#include "cylinder.h"

Cylinder::Cylinder(float r, float h, Material *mat)
{
	material = mat;
	radius = r;
	height = h;
}

bool Cylinder::intersect(const Ray &r, Hit &h, float tmin)
{
	d_Vec3f D = r.getDirection();
	d_Vec3f O = r.getOrigin();
	float A = D[1]*D[1] + D[0]*D[0];
	float B = 2*(O[0]*D[0] + O[1]*D[1]);
	float C = O[0]*O[0] + O[1]*O[1]-radius*radius;
	float disc = B*B - 4*A*C;
	float t0, t1;
	if(disc<0)
		return false;
	if(disc ==0)
	{
		t0 = -B/(2*A);
		if(t0>tmin&&t0<h.getT())
		{
			if(len(r.pointAtParameter(t0)*d_Vec3f(0,0,1))<height/2)
			{
				d_Vec3f normal = r.pointAtParameter(t0);
				normal = norm(normal-d_Vec3f(0,0,normal[2]));
				h.set(tmin, material, normal);
				return true;
			}
		}
	}
	else
	{
		t1 = (-B+sqrt(disc))/(2*A);
		t0 = (-B-sqrt(disc))/(2*A);
		if(t0>tmin&&t0<h.getT())
		{
			if(len(r.pointAtParameter(t0)*d_Vec3f(0,0,1))<height/2)
			{
				d_Vec3f normal = norm(r.pointAtParameter(t0)*d_Vec3f(1,1,0));
				h.set(tmin, material, normal);
				return true;
			}
			else if(len(r.pointAtParameter(t1)*d_Vec3f(0,0,1))<height/2)
			{
				d_Vec3f normal = norm(r.pointAtParameter(t1)*d_Vec3f(1,1,0));
				h.set(tmin, material, normal);
				return true;
			}
		}
	}
	return false;
}

bool Cylinder::inside(d_Vec3f point)
{
	if(sqrt(pow(point[0],2)+pow(point[1],2))&&point[2]<height/2&&point[2]>-height/2)
		return true;
	return false;
}

